#ifndef __74HC595_H
#define __74HC595_H

#include "main.h" 

// 引脚操作宏
#define HC595_DS_HIGH() HAL_GPIO_WritePin(HC595_DS_GPIO_Port, HC595_DS_Pin, GPIO_PIN_SET)
#define HC595_DS_LOW() HAL_GPIO_WritePin(HC595_DS_GPIO_Port, HC595_DS_Pin, GPIO_PIN_RESET)

#define HC595_SHCP_HIGH() HAL_GPIO_WritePin(HC595_SHCP_GPIO_Port, HC595_SHCP_Pin, GPIO_PIN_SET)
#define HC595_SHCP_LOW() HAL_GPIO_WritePin(HC595_SHCP_GPIO_Port, HC595_SHCP_Pin, GPIO_PIN_RESET)

#define HC595_STCP_HIGH() HAL_GPIO_WritePin(HC595_STCP_GPIO_Port, HC595_STCP_Pin, GPIO_PIN_SET)
#define HC595_STCP_LOW() HAL_GPIO_WritePin(HC595_STCP_GPIO_Port, HC595_STCP_Pin, GPIO_PIN_RESET)

// 输出控制结构体 (位域)   // M1占据最低位 小端存储 输入数据时先输入SSR和M10 最终595能按照对应顺序输出
typedef struct
{
    // 第一片74HC595 (Q0-Q7)
    uint32_t M8_EN : 1;   // Q0
    uint32_t M8_STEP : 1; // Q1
    uint32_t M8_DIR : 1;  // Q2
    uint32_t M7_EN : 1;   // Q3
    uint32_t M7_STEP : 1; // Q4
    uint32_t M7_DIR : 1;  // Q5
    uint32_t M6_EN : 1;   // Q6
    uint32_t M6_STEP : 1; // Q7

    // 第二片74HC595 (Q0-Q7)
    uint32_t M6_DIR : 1;  // Q0
    uint32_t M5_EN : 1;   // Q1
    uint32_t M5_STEP : 1; // Q2
    uint32_t M5_DIR : 1;  // Q3
    uint32_t M4_EN : 1;   // Q4
    uint32_t M4_STEP : 1; // Q5
    uint32_t M4_DIR : 1;  // Q6
    uint32_t M3_EN : 1;   // Q7

    // 第三片74HC595 (Q0-Q7)
    uint32_t M3_STEP : 1; // Q0
    uint32_t M3_DIR : 1;  // Q1
    uint32_t M2_EN : 1;   // Q2
    uint32_t M2_STEP : 1; // Q3
    uint32_t M2_DIR : 1;  // Q4
    uint32_t M1_EN : 1;   // Q5
    uint32_t M1_STEP : 1; // Q6
    uint32_t M1_DIR : 1;  // Q7

    // 第四片74HC595 (Q0-Q7)
    uint32_t M10_EN : 1;   // Q0
    uint32_t M10_STEP : 1; // Q1
    uint32_t M10_DIR : 1;  // Q2
    uint32_t M9_EN : 1;    // Q3
    uint32_t M9_STEP : 1;  // Q4
    uint32_t M9_DIR : 1;   // Q5
    uint32_t SSR1 : 1;     // Q6
    uint32_t SSR2 : 1;     // Q7
} HC595_Outputs_t;

// 联合体用于结构体与uint32_t的转换,raw就等于以M1占据最低位的字符串
typedef union
{
    HC595_Outputs_t outputs;
    uint32_t raw;
} HC595_Data_t;

// 函数声明
void hc595_init(void);
void hc595_send(uint32_t data);

#endif